﻿//=====================================================

//Copyright (C) 2016-2018 Fanjia

//All rights reserved

//CLR版 本:    4.0.30319.42000

//创建时间:     2018/11/14 15:17:34

//创 建 人:   徐晓航

//======================================================

using System;

namespace JobBatDeal.Common.EsTool
{
    public static class GeoCoordinateExtension
    {
        private const double Xpi = Math.PI * 3000 / 180;

        /// <summary>
        /// 将百度坐标系（BD-09）转换成火星坐标系（GCJ-02）
        /// </summary>
        /// <param name="geoCoordinate"></param>
        /// <returns>火星坐标系的经纬度</returns>
        public static GeoCoordinate TransformBd09ToGcj02(this GeoCoordinate geoCoordinate)
        {
            var longitude = geoCoordinate.Longitude;
            var latitude = geoCoordinate.Latitude;
            if (longitude < 72.004 || longitude > 137.8347 || latitude < 0.8293 || latitude > 55.8271)
            {
                return default;
            }
            var x = longitude - 0.0065;
            var y = latitude - 0.006;
            var z = Math.Sqrt(x * x + y * y) - 0.00002 * Math.Sin(y * Xpi);
            var theta = Math.Atan2(y, x) - 0.000003 * Math.Cos(x * Xpi);
            return new GeoCoordinate(z * Math.Sin(theta), z * Math.Cos(theta));
        }

        /// <summary>
        /// 获取地理距离
        /// </summary>
        /// <param name="source">来源</param>
        /// <param name="target">目标</param>
        /// <returns>地理距离</returns>
        public static double GetGeoDistance(this GeoCoordinate source, GeoCoordinate target)
        {
            if (source == default || target == default)
            {
                return default;
            }

            if (Math.Abs(source.Longitude) > 180 || Math.Abs(source.Latitude) > 90 ||
                Math.Abs(target.Longitude) > 180 || Math.Abs(target.Latitude) > 90)
            {
                return default;
            }

            return source.GetDistanceTo(target);
        }

        /// <summary>
        /// 获取坐标相似度
        /// </summary>
        /// <param name="source">来源</param>
        /// <param name="target">目标</param>
        /// <returns>坐标相似度</returns>
        public static double GetCoordinateSimilarity(this GeoCoordinate source, GeoCoordinate target)
        {
            try
            {
                var geoDistance = source.GetGeoDistance(target);
                return geoDistance <= 100 ? 1 : geoDistance > 1000 ? 0 : Math.Floor((1100 - geoDistance) / 100) / 10;
            }
            catch (Exception e)
            {
                return 0;
            }
        }
    }
}
